package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/yuebanlaosiji/gocelery/pkg/gocelery"
)

// Define a simple task that adds two numbers
func addTask(args []interface{}, kwargs map[string]interface{}) (interface{}, error) {
	if len(args) != 2 {
		return nil, fmt.Errorf("expected 2 arguments, got %d", len(args))
	}

	// Type assertions for the arguments
	a, ok := args[0].(float64)
	if !ok {
		return nil, fmt.Errorf("expected first argument to be a number")
	}

	b, ok := args[1].(float64)
	if !ok {
		return nil, fmt.Errorf("expected second argument to be a number")
	}

	result := a + b
	fmt.Printf("Task executed: %f + %f = %f\n", a, b, result)
	return result, nil
}

func main() {
	// Determine if we should run as a worker or client
	// Usage: ./simple worker|client
	if len(os.Args) != 2 {
		fmt.Println("Usage: ./simple worker|client")
		os.Exit(1)
	}

	mode := os.Args[1]

	// Configure Redis URL
	// For Redis without password:
	// redisURL := "redis://localhost:6379/0"

	// For Redis with password:
	redisURL := "redis://:Hewenyu1994@121.5.249.100:6379/0"

	// If Redis also has a username:
	// redisURL := "redis://username:password@localhost:6379/0"

	// Configuration
	config := gocelery.Config{
		BrokerURL:    redisURL,
		BackendURL:   redisURL,
		DefaultQueue: "celery",
		Concurrency:  2,
	}

	switch mode {
	case "worker":
		runWorker(config)
	case "client":
		runClient(config)
	default:
		fmt.Printf("Unknown mode: %s. Use 'worker' or 'client'\n", mode)
		os.Exit(1)
	}
}

func runWorker(config gocelery.Config) {
	// Create the worker
	worker, err := gocelery.NewWorker(config)
	if err != nil {
		log.Fatalf("Failed to create worker: %v", err)
	}

	// Register task handlers
	err = worker.Register("tasks.add", addTask)
	if err != nil {
		log.Fatalf("Failed to register task: %v", err)
	}

	fmt.Println("Starting worker...")
	err = worker.Start()
	if err != nil {
		log.Fatalf("Failed to start worker: %v", err)
	}

	// Handle graceful shutdown
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	fmt.Println("Worker started. Press Ctrl+C to stop.")

	<-sigChan
	fmt.Println("\nShutting down...")
	worker.Stop()
	fmt.Println("Worker stopped.")
}

func runClient(config gocelery.Config) {
	// Create the client
	client, err := gocelery.NewClient(config)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	defer client.Close()

	// Send a task
	taskID, err := client.SendTask("tasks.add", []interface{}{10, 20}, nil)
	if err != nil {
		log.Fatalf("Failed to send task: %v", err)
	}

	fmt.Printf("Task sent. ID: %s\n", taskID)

	// Wait for the result
	fmt.Println("Waiting for result...")
	result, err := client.WaitForResult(taskID, 10*time.Second)
	if err != nil {
		log.Fatalf("Failed to get result: %v", err)
	}

	fmt.Printf("Task result: %v\n", result)
}
